home *** CD-ROM | disk | FTP | other *** search
/ By Popular Request 2.0 / By Popular Request 2.0 (Arsenal Computer).ISO / amiga_6 / unrar100.lzx / unpack.c < prev    next >
C/C++ Source or Header  |  2002-01-31  |  16KB  |  742 lines

  1. /******    *****   ******
  2.  **   **  **   **  **   **      unRAR utility version 1.00e
  3.  ******   *******  ******       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.  **   **  **   **  **   **         FREE portable version
  5.  **   **  **   **  **   **         ~~~~~~~~~~~~~~~~~~~~~
  6.  
  7.      Unpacking algorithm procedures
  8.  
  9.    YOU DO NOT NEED CHANGING THERE ANYTHING.
  10.  
  11.  
  12.    NOTE: This code was modified by Derek Clarke to compile correctly on
  13.          SAS/C V6.x for the Amiga operating system.
  14.  
  15. */
  16.  
  17. void MakeTbl(void);               /* Makes Huffman table */
  18. void AddBit(unsigned int);    /* Shift buffer pointer to NBits */
  19. void CopyString(UWORD, unsigned int);            /* string copy */
  20. void ShortLZ(void);               /* unpacks short, near and special LZ codes */
  21. void LongLZ(void);                /* unpacks long and far LZ codes */
  22. void HuffDecode(void);            /* Huffman decoding */
  23. int  UnpWriteBuf(void);           /* writes output buffer */
  24. int  UnpReadBuf(int);            /* reads output buffer */
  25. void GetFlagsBuf(void);           /* gets flag byte */
  26. void UnpInitData(int);           /* reset initial data */
  27. void InitHuff(void);              /* initializing Huffman tables */
  28. void CorrHuff(UWORD *, UBYTE *);  /* Huffman table correction in case of overflow */
  29. void CreateEncTbl(HPBYTE);          /* create decoding tables */
  30. void CreateOneTbl(UWORD *, UBYTE *, UBYTE *, UBYTE);          /* subfunction of previous */
  31. int  unpack(HPBYTE, int (* UnpRead)(), int (* UnpWrite)(), int);                /* unpacking procedure itself */
  32.  
  33. #define     SUSPEND     1
  34. #define     SIZE_PBUF   0x2000
  35. #define     FIRST       1
  36. #define     NEXT        2
  37. #define     UNP_MEMORY  0x10010L+sizeof(struct UnpData)+ \
  38.                         sizeof(struct DecodeTables)+SIZE_PBUF
  39.  
  40.  
  41. UWORD hcdsh1[]={ 0x0001,0xa003,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  42.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  43.  
  44. UWORD hcdsh2[]={ 0x0002,0x4003,0x6003,0xa003,0xd004,0xe004,0xf005,0xf806,
  45.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  46.  
  47. UWORD hcdsh3[]={ 0x0001,0xa004,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  48.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  49.  
  50. UWORD hcdsh4[]={ 0x0002,0x4003,0x6003,0xa004,0xd004,0xe004,0xf005,0xf806,
  51.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  52.  
  53. UWORD hcdln0[]={ 0x8001,0x4002,0x2003,0x1004,0x0805,0x0406,0x0207,0x0108,
  54.                  0x0008,0 };
  55.  
  56. UWORD hcdln1[258],hcdln2[258];
  57. UWORD hcode0[258],hcode1[258],hcode2[258],hcode3[258],hcode4[258];
  58.  
  59. struct MakeHuffTabs
  60. {
  61.   UWORD *Table;
  62.   UBYTE HuffCodeCount[12];
  63. } MakeTab[]={
  64.  {hcdln1,{0  ,2  ,1  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,0   ,224}},
  65.  {hcdln2,{0  ,0  ,5  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,2   ,220}},
  66.  {hcode0,{0  ,0  ,0  ,8  ,8  ,8   ,9   ,0   ,0   ,0   ,0   ,224}},
  67.  {hcode1,{0  ,0  ,0  ,0  ,4  ,40  ,16  ,16  ,4   ,0   ,47  ,130}},
  68.  {hcode2,{0  ,0  ,0  ,0  ,2  ,5   ,46  ,64  ,116 ,24  ,0   ,0  }},
  69.  {hcode3,{0  ,0  ,0  ,0  ,0  ,2   ,14  ,202 ,33  ,6   ,0   ,0  }},
  70.  {hcode4,{0  ,0  ,0  ,0  ,0  ,0   ,0   ,255 ,2   ,0   ,0   ,0  }}};
  71.  
  72.  
  73. SDWORD DestUnpSize=0;
  74. UBYTE  FlagBuf;
  75. UWORD  InAdr,OutAdr;
  76.  
  77. unsigned int Suspend=0;
  78. unsigned int NumBit;
  79. unsigned int LCount;
  80. int FlagsCnt;
  81.  
  82. struct UnpData
  83. {
  84.   UWORD ChSet[256];
  85.   UBYTE Place[256];
  86.   UBYTE NToPl[256];
  87.  
  88.   UBYTE ChSetA[256];
  89.   UBYTE PlaceA[256];
  90.  
  91.   UWORD ChSetB[256];
  92.   UBYTE PlaceB[256];
  93.   UBYTE NToPlB[256];
  94.  
  95.   UWORD ChSetC[256];
  96.   UBYTE PlaceC[256];
  97.   UBYTE NToPlC[256];
  98.  
  99.   UWORD AvrPlc;
  100.   UWORD AvrPlcB;
  101.   UWORD AvrLn1;
  102.   UWORD AvrLn2;
  103.   UWORD AvrLn3;
  104.  
  105.   UBYTE NumHuf;
  106.   UBYTE StMode;
  107.  
  108.   UWORD Nhfb;
  109.   UWORD Nlzb;
  110.  
  111.   UWORD MaxDist3;
  112.   UBYTE Buf60;
  113.   UWORD WrAddr;
  114.   UWORD SomeRd;
  115.   UWORD UnpAllBuf;
  116.  
  117.   UWORD LastDist;
  118.   UWORD LastLen;
  119.   UWORD OldDist[4];
  120.   UWORD OldDistNum;
  121. } *D;
  122.  
  123.  
  124. struct DecodeTables
  125. {
  126.   UBYTE ECDSH1[256];
  127.   UBYTE ECDSH2[256];
  128.   UBYTE ECDSH3[256];
  129.   UBYTE ECDSH4[256];
  130.  
  131.   UBYTE ECDLN0[256];
  132.   UBYTE ECDLN1[4096];
  133.   UBYTE ECDLN2[4096];
  134.   UBYTE ECODE0[4096];
  135.   UBYTE ECODE1[4096];
  136.   UBYTE ECODE2[1024];
  137.   UBYTE ECODE3[1024];
  138.   UBYTE ECODE4[1024];
  139.   UBYTE NCDSH1[16];
  140.   UBYTE NCDSH2[16];
  141.   UBYTE NCDSH3[16];
  142.   UBYTE NCDSH4[16];
  143.   UBYTE NCDLN0[256];
  144.   UBYTE NCDLN1[256];
  145.   UBYTE NCDLN2[256];
  146.   UBYTE NCODE0[257];
  147.   UBYTE NCODE1[257];
  148.   UBYTE NCODE2[257];
  149.   UBYTE NCODE3[257];
  150.   UBYTE NCODE4[257];
  151. } *T;
  152.  
  153. UBYTE *PackBuf;
  154. HPBYTE UnpBuf;
  155.  
  156. int (* UnpReadFn)(UBYTE *, UWORD);
  157. int (* UnpWriteFn)(UBYTE *, UWORD);
  158.  
  159.  
  160. #define GetField() ((UWORD)((((UDWORD)PackBuf[InAdr] << 16) |         \
  161.                    ((UWORD)PackBuf[InAdr+1] << 8) | PackBuf[InAdr+2]) \
  162.                     >> (8-NumBit)))
  163.  
  164. void AddBit(unsigned int NBits)
  165. {
  166.   InAdr += (NumBit+NBits) >> 3;
  167.   NumBit = (NumBit+NBits) & 7;
  168. }
  169.  
  170. void CopyString(UWORD Distance, unsigned int Length)
  171. {
  172.   DestUnpSize-=Length;
  173.   while (Length--)
  174.   {
  175.     UnpBuf[OutAdr]=UnpBuf[(UWORD)(OutAdr-Distance)];
  176.     OutAdr++;
  177.   }
  178. }
  179.  
  180. int unpack(HPBYTE UnpMem, int (* UnpRead)(), int (* UnpWrite)(), int Solid)
  181. {
  182.   UnpReadFn=UnpRead;
  183.   UnpWriteFn=UnpWrite;
  184.   UnpBuf=(UBYTE *)UnpMem;
  185.   PackBuf=(UBYTE *)(UnpMem+0x10000L+sizeof(struct UnpData)+sizeof(struct DecodeTables));
  186.   D=(struct UnpData *)(UnpMem+0x10000L);
  187.  
  188.   if (Suspend)
  189.     OutAdr=D->WrAddr;
  190.   else
  191.   {
  192.     UnpInitData(Solid);
  193.     if (!Solid)
  194.     {
  195.       InitHuff();
  196.       memset(UnpBuf,0,0x8000);
  197.       memset(UnpBuf+0x8000,0,0x8000);
  198.       OutAdr=0;
  199.     }
  200.     else
  201.       OutAdr=D->WrAddr;
  202.     if (--DestUnpSize < 0)
  203.       return(0);
  204.  
  205.     if (UnpReadBuf(FIRST)==-1)
  206.       return(-1);
  207.  
  208.     GetFlagsBuf();
  209.     FlagsCnt=8;
  210.   }
  211.  
  212.   while (DestUnpSize>=0)
  213.   {
  214.     if (InAdr >= SIZE_PBUF-12)
  215.       if (UnpReadBuf(NEXT)==-1)
  216.         return(-1);
  217.     if ((UWORD)(D->WrAddr - OutAdr) < 0x110 && D->WrAddr!=OutAdr)
  218.     {
  219.       if (UnpWriteBuf()==-1)
  220.         return(-1);
  221.       if (Suspend)
  222.         return(0);
  223.     }
  224.  
  225.     if (D->StMode)
  226.     {
  227.       HuffDecode();
  228.       continue;
  229.     }
  230.  
  231.     if (--FlagsCnt < 0)
  232.     {
  233.       GetFlagsBuf();
  234.       FlagsCnt=7;
  235.     }
  236.  
  237.     if (FlagBuf >= 0x80)
  238.     {
  239.       FlagBuf<<=1;
  240.       if (D->Nlzb > D->Nhfb)
  241.         LongLZ();
  242.       else
  243.         HuffDecode();
  244.     }
  245.     else
  246.     {
  247.       FlagBuf<<=1;
  248.       if (--FlagsCnt < 0)
  249.       {
  250.         GetFlagsBuf();
  251.         FlagsCnt=7;
  252.       }
  253.       if (FlagBuf >= 0x80)
  254.       {
  255.         FlagBuf<<=1;
  256.         if (D->Nlzb > D->Nhfb)
  257.           HuffDecode();
  258.         else
  259.           LongLZ();
  260.       }
  261.       else
  262.       {
  263.         FlagBuf<<=1;
  264.         ShortLZ();
  265.       }
  266.     }
  267.   }
  268.   if (UnpWriteBuf()==-1)
  269.     return(-1);
  270.   return(0);
  271. }
  272.  
  273.  
  274. void ShortLZ(void)
  275. {
  276.   UWORD LengthCode,SaveLength;
  277.   UBYTE LastDistance;
  278.   UWORD Distance,DistancePlace,Length;
  279.   D->NumHuf=0;
  280.   LengthCode=GetField();
  281.   if (LCount==2)
  282.   {
  283.     AddBit(1);
  284.     if (LengthCode >= 0x8000)
  285.     {
  286.       CopyString(D->LastDist,D->LastLen);
  287.       return;
  288.     }
  289.     LengthCode <<= 1;
  290.     LCount=0;
  291.   }
  292.   LengthCode >>= 8;
  293.   if (D->Buf60==0)
  294.     if (D->AvrLn1<37)
  295.     {
  296.       Length=T->ECDSH1[LengthCode];
  297.       AddBit(T->NCDSH1[Length]);
  298.     }
  299.     else
  300.     {
  301.       Length=T->ECDSH2[LengthCode];
  302.       AddBit(T->NCDSH2[Length]);
  303.     }
  304.   else
  305.     if (D->AvrLn1<37)
  306.     {
  307.       Length=T->ECDSH3[LengthCode];
  308.       AddBit(T->NCDSH3[Length]);
  309.     }
  310.     else
  311.     {
  312.       Length=T->ECDSH4[LengthCode];
  313.       AddBit(T->NCDSH4[Length]);
  314.     }
  315.  
  316.   if (Length >= 9)
  317.   {
  318.     if (Length == 9)
  319.     {
  320.       LCount++;
  321.       CopyString(D->LastDist,D->LastLen);
  322.       return;
  323.     }
  324.     if (Length == 14)
  325.     {
  326.       LCount=0;
  327.       Length=T->ECDLN2[GetField() >> 4];
  328.       AddBit(T->NCDLN2[Length]);
  329.       Length+=5;
  330.       Distance=(GetField() >> 1) | 0x8000;
  331.       AddBit(15);
  332.       D->LastLen=Length;
  333.       D->LastDist=Distance;
  334.       CopyString(Distance,Length);
  335.       return;
  336.     }
  337.  
  338.     LCount=0;
  339.     SaveLength=Length;
  340.     Distance=D->OldDist[(D->OldDistNum-(Length-9)) & 3];
  341.     Length=T->ECDLN1[GetField() >> 4];
  342.     AddBit(T->NCDLN1[Length]);
  343.     Length+=2;
  344.     if (Length==0x101 && SaveLength==10)
  345.     {
  346.       D->Buf60 ^= 1;
  347.       return;
  348.     }
  349.     if (Distance > 256)
  350.       Length++;
  351.     if (Distance > D->MaxDist3)
  352.       Length++;
  353.  
  354.     D->OldDist[D->OldDistNum++]=Distance;
  355.     D->OldDistNum = D->OldDistNum & 3;
  356.     D->LastLen=Length;
  357.     D->LastDist=Distance;
  358.     CopyString(Distance,Length);
  359.     return;
  360.   }
  361.  
  362.   LCount=0;
  363.   D->AvrLn1 += Length;
  364.   D->AvrLn1 -= D->AvrLn1 >> 4;
  365.  
  366.   DistancePlace=T->ECODE2[GetField() >> 6];
  367.   AddBit(T->NCODE2[DistancePlace]);
  368.   Distance=D->ChSetA[DistancePlace];
  369.   if (--DistancePlace != 0xFFFF)
  370.   {
  371.     D->PlaceA[Distance]--;
  372.     LastDistance=D->ChSetA[DistancePlace];
  373.     D->PlaceA[LastDistance]++;
  374.     D->ChSetA[DistancePlace+1]=LastDistance;
  375.     D->ChSetA[DistancePlace]=(UBYTE)Distance;
  376.   }
  377.   Length+=2;
  378.   D->OldDist[D->OldDistNum++] = ++Distance;
  379.   D->OldDistNum = D->OldDistNum & 3;
  380.   D->LastLen=Length;
  381.   D->LastDist=Distance;
  382.   CopyString(Distance,Length);
  383.   return;
  384. }
  385.  
  386.  
  387. void LongLZ(void)
  388. {
  389.   UWORD LengthCode,Length;
  390.   UWORD Distance,DistancePlace,NewDistancePlace;
  391.   UWORD oldav2,oldav3;
  392.  
  393.   D->NumHuf=0;
  394.   D->Nlzb+=16;
  395.   if (D->Nlzb > 0xff)
  396.   {
  397.     D->Nlzb=0x90;
  398.     D->Nhfb >>= 1;
  399.   }
  400.   oldav2=D->AvrLn2;
  401.   if (D->AvrLn2 >= 122)
  402.   {
  403.     Length=T->ECDLN2[GetField() >> 4];
  404.     AddBit(T->NCDLN2[Length]);
  405.   }
  406.   else
  407.     if (D->AvrLn2 >= 64)
  408.     {
  409.       Length=T->ECDLN1[GetField() >> 4];
  410.       AddBit(T->NCDLN1[Length]);
  411.     }
  412.     else
  413.     {
  414.       LengthCode=GetField();
  415.       if (LengthCode < 0x100)
  416.       {
  417.         Length=LengthCode;
  418.         AddBit(16);
  419.       }
  420.       else
  421.       {
  422.         Length=T->ECDLN0[LengthCode >> 8];
  423.         AddBit(T->NCDLN0[Length]);
  424.       }
  425.     }
  426.  
  427.   D->AvrLn2 += Length;
  428.   D->AvrLn2 -= D->AvrLn2 >> 5;
  429.   if (D->AvrPlcB > 0x28ff)
  430.   {
  431.     DistancePlace=T->ECODE2[GetField() >> 6];
  432.     AddBit(T->NCODE2[DistancePlace]);
  433.   }
  434.   else
  435.     if (D->AvrPlcB > 0x6ff)
  436.     {
  437.       DistancePlace=T->ECODE1[GetField() >> 4];
  438.       AddBit(T->NCODE1[DistancePlace]);
  439.     }
  440.     else
  441.     {
  442.       DistancePlace=T->ECODE0[GetField() >> 4];
  443.       AddBit(T->NCODE0[DistancePlace]);
  444.     }
  445.  
  446.   D->AvrPlcB += DistancePlace;
  447.   D->AvrPlcB -= D->AvrPlcB >> 8;
  448.   while (1)
  449.   {
  450.     Distance = D->ChSetB[DistancePlace];
  451.     NewDistancePlace = D->NToPlB[Distance++ & 0xff]++;
  452.     if (!(Distance & 0xff))
  453.     {
  454.       Distance-=0x100;
  455.       CorrHuff(D->ChSetB,D->NToPlB);
  456.     }
  457.     else
  458.       break;
  459.   }
  460.  
  461.   D->ChSetB[DistancePlace]=D->ChSetB[NewDistancePlace];
  462.   D->ChSetB[NewDistancePlace]=Distance;
  463.  
  464.   Distance=((UWORD)((Distance & ~0xff) | (GetField() >> 8))) >> 1;
  465.   AddBit(7);
  466.  
  467.   oldav3=D->AvrLn3;
  468.   if (Length!=1 && Length!=4)
  469.     if (Length==0 && Distance <= D->MaxDist3)
  470.     {
  471.       D->AvrLn3++;
  472.       D->AvrLn3 -= D->AvrLn3 >> 8;
  473.     }
  474.     else
  475.       if (D->AvrLn3 > 0)
  476.         D->AvrLn3--;
  477.   Length+=3;
  478.   if (Distance >= D->MaxDist3)
  479.     Length++;
  480.   if (Distance <= 256)
  481.     Length+=8;
  482.   if (oldav3 > 0xb0 || D->AvrPlc >= 0x2a00 && oldav2 < 0x40)
  483.     D->MaxDist3=0x7f00;
  484.   else
  485.     D->MaxDist3=0x2001;
  486.   D->OldDist[D->OldDistNum++]=Distance;
  487.   D->OldDistNum = D->OldDistNum & 3;
  488.   D->LastLen=Length;
  489.   D->LastDist=Distance;
  490.   CopyString(Distance,Length);
  491. }
  492.  
  493.  
  494. void HuffDecode(void)
  495. {
  496.   UWORD CurByte,BytePlace,NewBytePlace;
  497.   UWORD Length,Distance,Code;
  498.  
  499.   Code=GetField();
  500.  
  501.   if (D->AvrPlc > 0x75ff)
  502.   {
  503.     BytePlace=T->ECODE4[Code>>6];
  504.     if (D->StMode && BytePlace==0 && Code > 0xfff)
  505.       BytePlace=0x100;
  506.     AddBit(T->NCODE4[BytePlace]);
  507.   }
  508.   else
  509.     if (D->AvrPlc > 0x5dff)
  510.     {
  511.       BytePlace=T->ECODE3[Code>>6];
  512.       if (D->StMode && BytePlace==0 && Code > 0xfff)
  513.         BytePlace=0x100;
  514.       AddBit(T->NCODE3[BytePlace]);
  515.     }
  516.     else
  517.       if (D->AvrPlc > 0x35ff)
  518.       {
  519.         BytePlace=T->ECODE2[Code>>6];
  520.         if (D->StMode && BytePlace==0 && Code > 0xfff)
  521.           BytePlace=0x100;
  522.         AddBit(T->NCODE2[BytePlace]);
  523.       }
  524.       else
  525.         if (D->AvrPlc > 0x0dff)
  526.         {
  527.           BytePlace=T->ECODE1[Code>>4];
  528.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  529.             BytePlace=0x100;
  530.           AddBit(T->NCODE1[BytePlace]);
  531.         }
  532.         else
  533.         {
  534.           BytePlace=T->ECODE0[Code>>4];
  535.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  536.             BytePlace=0x100;
  537.           AddBit(T->NCODE0[BytePlace]);
  538.         }
  539.   if (D->StMode)
  540.   {
  541.     if (--BytePlace==0xFFFF)
  542.     {
  543.       Code=GetField();
  544.       AddBit(1);
  545.       if (Code >= 0x8000)
  546.       {
  547.         D->NumHuf=D->StMode=0;
  548.         return;
  549.       }
  550.       else
  551.       {
  552.         Length = (Code & 0x4000) ? 4 : 3;
  553.         Distance= T->ECODE2[(Code >> 4) & 0x3ff];
  554.         AddBit(T->NCODE2[Distance]+1);
  555.         Distance = (Distance << 5) | (GetField() >> 11);
  556.         AddBit(5);
  557.         CopyString(Distance,Length);
  558.         return;
  559.       }
  560.     }
  561.   }
  562.   else
  563.     if (D->NumHuf++ >= 16 && FlagsCnt==0)
  564.       D->StMode=1;
  565.   D->AvrPlc += BytePlace;
  566.   D->AvrPlc -= D->AvrPlc >> 8;
  567.   D->Nhfb+=16;
  568.   if (D->Nhfb > 0xff)
  569.   {
  570.     D->Nhfb=0x90;
  571.     D->Nlzb >>= 1;
  572.   }
  573.  
  574.   UnpBuf[OutAdr++]=(UBYTE)(D->ChSet[BytePlace]>>8);
  575.   DestUnpSize--;
  576.  
  577.   while (1)
  578.   {
  579.     CurByte=D->ChSet[BytePlace];
  580.     NewBytePlace=D->NToPl[CurByte++ & 0xff]++;
  581.     if ((CurByte & 0xff) > 0xa1)
  582.       CorrHuff(D->ChSet,D->NToPl);
  583.     else
  584.       break;
  585.   }
  586.  
  587.   D->ChSet[BytePlace]=D->ChSet[NewBytePlace];
  588.   D->ChSet[NewBytePlace]=CurByte;
  589. }
  590.  
  591.  
  592. int UnpWriteBuf(void)
  593. {
  594.   if (OutAdr<D->WrAddr)
  595.   {
  596.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)-D->WrAddr)==-1 ||
  597.         UnpWriteFn((UBYTE *)UnpBuf,(UWORD)OutAdr)==-1)
  598.       return(-1);
  599.   }
  600.   else
  601.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)(OutAdr-D->WrAddr))==-1)
  602.       return(-1);
  603.   D->WrAddr=OutAdr;
  604.   return(0);
  605. }
  606.  
  607.  
  608. int UnpReadBuf(int NumBuf)
  609. {
  610.   int ReadCode;
  611.   if (NumBuf==FIRST)
  612.     ReadCode=UnpReadFn(PackBuf,SIZE_PBUF);
  613.   else
  614.   {
  615.     memcpy(PackBuf,PackBuf+InAdr,(UWORD)(SIZE_PBUF-InAdr));
  616.     ReadCode=UnpReadFn(PackBuf+SIZE_PBUF-InAdr,(UWORD)InAdr);
  617.   }
  618.   InAdr=0;
  619.   if (ReadCode==-1)
  620.     return(-1);
  621.   return(0);
  622. }
  623.  
  624. void GetFlagsBuf(void)
  625. {
  626.   UWORD Flags,FlagsPlace,NewFlagsPlace;
  627.  
  628.   FlagsPlace=T->ECODE2[GetField() >> 6];
  629.   AddBit(T->NCODE2[FlagsPlace]);
  630.  
  631.   while (1)
  632.   {
  633.     Flags=D->ChSetC[FlagsPlace];
  634.     FlagBuf=(UBYTE)(Flags >> 8);
  635.     NewFlagsPlace=D->NToPlC[Flags++ & 0xff]++;
  636.     if ((Flags & 0xff) == 0)
  637.     {
  638.       Flags-=0x100;
  639.       CorrHuff(D->ChSetC,D->NToPlC);
  640.     }
  641.     else
  642.       break;
  643.   }
  644.  
  645.   D->ChSetC[FlagsPlace]=D->ChSetC[NewFlagsPlace];
  646.   D->ChSetC[NewFlagsPlace]=Flags;
  647. }
  648.  
  649.  
  650. void UnpInitData(int Solid)
  651. {
  652.   if (!Solid)
  653.   {
  654.     memset(D,0,sizeof(struct UnpData));
  655.     D->AvrPlc=0x3500;
  656.     D->MaxDist3=0x2001;
  657.     D->Nhfb=D->Nlzb=0x80;
  658.   }
  659.   FlagsCnt=0;
  660.   FlagBuf=0;
  661.   InAdr=0;
  662.   NumBit=0;
  663.   D->StMode=0;
  664.   LCount=0;
  665. }
  666.  
  667. void InitHuff(void)
  668. {
  669.   UWORD I;
  670.   for (I=0;I<256;I++)
  671.   {
  672.     D->Place[I]=D->PlaceA[I]=D->PlaceB[I]=(UBYTE)I;
  673.     D->PlaceC[I]=(UBYTE)(~I+1);
  674.     D->ChSet[I]=D->ChSetB[I]=I<<8;
  675.     D->ChSetA[I]=(UBYTE)I;
  676.     D->ChSetC[I]=(~I+1)<<8;
  677.   }
  678.   memset(D->NToPl,0,sizeof(D->NToPl));
  679.   memset(D->NToPlB,0,sizeof(D->NToPlB));
  680.   memset(D->NToPlC,0,sizeof(D->NToPlC));
  681.   CorrHuff(D->ChSetB,D->NToPlB);
  682. }
  683.  
  684.  
  685. void CorrHuff(UWORD *CharSet, UBYTE *NumToPlace)
  686. {
  687.   int I,J;
  688.   for (I=7;I>=0;I--)
  689.     for (J=0;J<32;J++,CharSet++)
  690.       *CharSet=(*CharSet & ~0xff) | I;
  691.   memset(NumToPlace,0,sizeof(D->NToPl));
  692.   for (I=6;I>=0;I--)
  693.     NumToPlace[I]=(7-I)*32;
  694. }
  695.  
  696. void CreateEncTbl(HPBYTE UnpMem)
  697. {
  698.   T=(struct DecodeTables *)(UnpMem+0x10000L+sizeof(struct UnpData));
  699.   CreateOneTbl(hcdsh1,T->ECDSH1,T->NCDSH1,8);
  700.   CreateOneTbl(hcdsh2,T->ECDSH2,T->NCDSH2,8);
  701.   CreateOneTbl(hcdsh3,T->ECDSH3,T->NCDSH3,8);
  702.   CreateOneTbl(hcdsh4,T->ECDSH4,T->NCDSH4,8);
  703.   CreateOneTbl(hcdln0,T->ECDLN0,T->NCDLN0,8);
  704.   CreateOneTbl(hcdln1,T->ECDLN1,T->NCDLN1,4);
  705.   CreateOneTbl(hcdln2,T->ECDLN2,T->NCDLN2,4);
  706.   CreateOneTbl(hcode0,T->ECODE0,T->NCODE0,4);
  707.   CreateOneTbl(hcode1,T->ECODE1,T->NCODE1,4);
  708.   CreateOneTbl(hcode2,T->ECODE2,T->NCODE2,6);
  709.   CreateOneTbl(hcode3,T->ECODE3,T->NCODE3,6);
  710.   CreateOneTbl(hcode4,T->ECODE4,T->NCODE4,6);
  711. }
  712.  
  713.  
  714. void CreateOneTbl(UWORD *hcd, UBYTE *ecd, UBYTE *ncd, UBYTE ShiftCount)
  715. {
  716.   UWORD I,MaxCode,Code;
  717.   for (I=0; hcd[I]; I++)
  718.   {
  719.     ncd[I]=(UBYTE)(hcd[I] & 0xf);
  720.     Code=hcd[I] >> ShiftCount;
  721.     MaxCode=1 << (16-ShiftCount-(UBYTE)(hcd[I] & 0xf));
  722.     while (MaxCode--)
  723.       ecd[Code++]=(UBYTE)I;
  724.   }
  725. }
  726.  
  727.  
  728. void MakeTbl(void)
  729. {
  730.   UWORD I,J,K,Code;
  731.   UWORD *OutTab;
  732.   for (I=0;I<sizeof(MakeTab)/sizeof(MakeTab[0]);I++)
  733.   {
  734.     OutTab=MakeTab[I].Table;
  735.     for (Code=J=0;J<12;J++)
  736.       for (Code<<=1,K=0;K<MakeTab[I].HuffCodeCount[J];K++)
  737.         *(OutTab++)=(Code++ << (4+11-J)) | (J + 1);
  738.     *OutTab=0;
  739.   }
  740. }
  741.  
  742.